package legoclient;

import ServerClient.*;
import java.net.MalformedURLException;

import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.media.control.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
import javax.media.*;
import javax.media.util.*;
import javax.media.format.*;

public class JmfPanel extends JPanel implements ActionListener, ControllerListener {

    private static final long serialVersionUID = 1L;
    private String media;
    private boolean started = false;
    private ClientGUI GUI;
    private ClientBackend backend;
    private Component visualComponent = new JLabel(new ImageIcon(getClass().getResource("dud.png")));
    private JLabel dud = new JLabel(new ImageIcon(getClass().getResource("dud.png")));
    private JLabel connectionLabel = new JLabel("Not Connected");
    private Player player;

    public boolean startStream(String media) {
        this.media = media;
        try {
            update("Connecting to: " + media);
            this.connectionLabel.setText("Connecting to: " + media);
            //player = Manager.createPlayer(new URL("file:///tmp/a.mpg"));
            this.player = Manager.createPlayer(new MediaLocator(media));
            this.player.addControllerListener(this);
            this.player.start();
        } catch (NoPlayerException e) {
            e.printStackTrace();
            return false;
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public JmfPanel(ClientGUI GUIin, ClientBackend backendin) {

        this.GUI = GUIin;
        this.backend = backendin;
        this.setLayout(new BorderLayout());
        setBorder(BorderFactory.createTitledBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED), "Webcam"));
        this.add(dud, BorderLayout.CENTER);
        this.add(connectionLabel, BorderLayout.SOUTH);

    //this.startStream();

    }

    public void update(String s) {
        if (GUI != null) {
            GUI.update("JmfPanel: " + s);
        }
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    }

    public void actionPerformed(ActionEvent e) {

    }

    public void controllerUpdate(ControllerEvent c) {
        if (player == null) {
            return;
        }

        if (c instanceof RealizeCompleteEvent) {

            if ((visualComponent = player.getVisualComponent()) != null) {
                update("Connected to RTP stream");
                this.connectionLabel.setText("Connected to " + this.media);
            }
            this.remove(dud);
            this.add(visualComponent, BorderLayout.CENTER);
            visualComponent.addMouseListener(new MouseListener() {

                private int clickCount = 0;
                private Point startPos;
                private Point endPos;

                public void mouseClicked(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");

                }

                public void mousePressed(MouseEvent e) {
                    //throw new UnsupportedOperationException("Not supported yet.");
                    if (clickCount == 1) {
                        update("EndPos set X: " + e.getX() + " Y: " + e.getY());
                        this.endPos = new Point(e.getX(), e.getY());
                        clickCount = 0;
                        Image snapshot = grabFrame();
                        
                        //testing code
                        //BufferedImage buffImg = new BufferedImage(snapshot.getWidth(null), snapshot.getHeight(null), BufferedImage.TYPE_INT_RGB);
                        
                        /*BufferedImage buffImg = (BufferedImage) snapshot;
                        try {
                            ImageIO.write(buffImg, "jpg", new File("c:\\webcam.jpg"));
                        }catch(IOException exc) {
                            System.err.println("EXCEPTION WRITING TEST IMAGE TO DISK.");
                        }*/
                        
                        update("Sending Command...");
                        backend.writeCmd(new ClientServerCmd(ClientServerCmd.GOTO, this.startPos, this.endPos, snapshot));
                        update("Command Sent.");
                    } else {
                        update("StartPos set X: " + e.getX() + " Y: " + e.getY());
                        this.startPos = new Point(e.getX(), e.getY());
                        clickCount = 1;
                    }
                }

                public void mouseReleased(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
                }

                public void mouseEntered(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
                }

                public void mouseExited(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
                }
            });
            GUI.pack();

        }
        // @TODO Handle connection loss here 
        //else if(c instanceof )
    }
    
    public Image grabFrame() {
        FrameGrabbingControl frameGrabber = (FrameGrabbingControl)player.getControl("javax.media.control.FrameGrabbingControl");
        
        if(frameGrabber == null) {
            update("Failed to create frame grabbing control.");
            return null;
        }
        Buffer buf = frameGrabber.grabFrame();
        if(buf == null) {
            update("Failed to grab buffered image.");
            return null;
        }

        // Convert frame to an buffered image so it can be processed and saved
        Image img = (new BufferToImage((VideoFormat)buf.getFormat()).createImage(buf));
        //BufferedImage buffImg = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
        //Graphics2D g = buffImg.createGraphics();
        //g.drawImage(img, null, null);
        // Save image to disk as PNG
        //ImageIO.write(buffImg, "png", new File("c:\\webcam.png"));   // change the two "png"s to "jpg" i guess??
        
        return img;
    }
}
